const std = @import("std");
fn maxPlus(comptime T: type, a: T, b: T) !ErrorCode {
    if (T == bool) {
        std.debug.print("a +b   true  ", .{});
        return ErrorCode{ .InvalidInput = "Invalid Input" };
    } else if (a > b) {
        std.debug.print("a > b ,{}  ", .{a > b});
        return ErrorCode.InvalidInput;
    } else {
        std.debug.print("a < b {} ", .{a < b});
        return ErrorCode.InvalidState;
    }
}
const ErrorCode = union {
    InvalidInput: []const u8,
    InvalidOutput: i32,
    InvalidOperation: f64,
    InvalidState: ?[]const u8,
    InvalidFormat: ?bool,
};

const MyError = enum(u8) {
    InvalidInput = 1,
    InvalidOutput = 2,
    InvalidOperation = 3,
};
const Result = union(enum) {
    success: bool,
    err: MyError,
};

pub fn processData(input: i32) !Result {
    if (input < 0) {
        return Result{ .err = MyError.InvalidOutput };
    }
    if (input > 100) {
        return Result{ .err = MyError.InvalidOperation };
    }
    return Result{ .success = true };
}

pub fn union_type() !void {
    const result = try processData(3425);
    switch (result) {
        .success => |success| {
            std.debug.print("success: {}\n", .{success});
        },
        .err => |err| {
            std.debug.print("error: {}\n", .{err});
        },
    }
}

const MyStruct = struct {
    field1: i32 = 10,
    field2: f64 = 23432.12,
    name: []const u8 = "John",
    age: ?u32 = 25,
};
pub fn init_gpa_examplpe() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    const allocator = gpa.allocator();
    defer {
        const deinit = gpa.deinit();
        if (deinit == .leak) {
            std.debug.print("Memory leak detected\n", .{});
            @panic("Memory leak detected");
        }
    }
    const bytes = try allocator.alloc(u8, 100);
    defer allocator.free(bytes);
}

const empty_struct = struct { name: []const u8 = "mike", age: ?u32 = 213 };
pub fn test_empty_tuple_arg(input: anytype, age: u32) !void {
    const tuple = .{ 123, 324 };
    _ = tuple;
    const T = @TypeOf(input);
    if (@typeInfo(T) != .Struct) {
        return error.NotAStruct;
    }

    //  std.debug.print("tuple: {}\n", .{tuple.@"1"});
    if (@typeInfo(@TypeOf(input)) == .Struct or
        @typeInfo(@TypeOf(input)) == .Tuple)
    {
        const tuple_age = input[0];
        const tuple_name = input[1];
        std.debug.print("tuple_age: {any}, tuple_name: {any}\n", .{ tuple_age, tuple_name });

        std.debug.print("input is empty\n {} ", .{input});
    } else {
        std.debug.print("input is not empty\n {} ", .{input});
    }
    const info = @typeInfo(@TypeOf(age));
    std.debug.print("type info: {}\n", .{info.Int.bits}); // 获取反射的值
}

pub fn test_struct() void {
    const empty = empty_struct{};
    std.debug.print("empty_struct: {s}\n", .{empty.name});
    const my_struct = MyStruct{ .field1 = 20, .age = 30 };
    std.debug.print("my_struct: {any}\n", .{my_struct});
}
pub fn iife() void {
    (struct {
        fn run() void {
            std.debug.print("Hello from an unnamed anonymous function!\n", .{});
        }
    }).run();
}
pub fn main() !void {
    iife();
}
